package com.agree.util.excel.config;

import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.agree.util.excel.enums.MappingType;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by wangmu on 2017/12/6.
 */
public class Configuration {

    private DbConfig dbConfig;
    private MappingConfig mppingConfig;
    private POIConfig poiConfig;

    public DbConfig dbConfig() {
        if(this.dbConfig == null) {
            this.dbConfig = new DbConfig();
        }
        return this.dbConfig;
    }

    public MappingConfig mppingConfig() {
        if(this.mppingConfig == null) {
            this.mppingConfig = new MappingConfig();
        }
        return this.mppingConfig;
    }

    public POIConfig poiConfig() {
        if(this.poiConfig == null) {
            this.poiConfig = new POIConfig();
        }
        return this.poiConfig;
    }

    public class DbConfig {
        private String driverClassName;
        private String url;
        private String username;
        private String password;
        private String[] includTables;
        private String[] commonPrefix = {"TB_UCC"};

        public String driverClassName() {
            return driverClassName;
        }

        public DbConfig driverClassName(String driverClassName) {
            this.driverClassName = driverClassName;
            return this;
        }

        public String url() {
            return url;
        }

        public DbConfig url(String url) {
            this.url = url;
            return this;
        }

        public String username() {
            return username;
        }

        public DbConfig username(String username) {
            this.username = username;
            return this;
        }

        public String password() {
            return password;
        }

        public DbConfig password(String password) {
            this.password = password;
            return this;
        }

        public String[] includTables() {
            return includTables;
        }

        public DbConfig includTables(String[] includTables) {
            this.includTables = includTables;
            return this;
        }

        public String[] commonPrefix() {
            return commonPrefix;
        }

        public DbConfig commonPrefix(String[] commonPrefix) {
            this.commonPrefix = commonPrefix;
            return this;
        }

        public Configuration end() {
            return Configuration.this;
        }

        @Override
        public String toString() {
            return "DbConfig{" +
                    "driverClassName='" + driverClassName + '\'' +
                    ", url='" + url + '\'' +
                    ", username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", includTables=" + Arrays.toString(includTables) +
                    ", commonPrefix=" + Arrays.toString(commonPrefix) +
                    '}';
        }
    }

    public class MappingConfig {
        @Deprecated
        private MappingType[] mappingTypes;

        private boolean isCustomParams = false;//若为true需要定义inParamsFilePath和outParamsFilePath

        private String inParamsFilePath = "in.txt";

        private String outParamsFilePath = "out.txt";

        private TableMapping tableMapping;

        @Deprecated
        public MappingType[] mappingTypes() {
            return mappingTypes;
        }

        @Deprecated
        /**
         * @see TableMapping
         */
        public MappingConfig mappingTypes(MappingType[] mappingTypes) {
            this.mappingTypes = mappingTypes;
            return this;
        }

        public TableMapping tableMappings() {
            if(tableMapping == null) {
                tableMapping = new TableMapping();
            }
            return tableMapping;
        }

        @Deprecated
        public boolean isCustomParams() {
            return isCustomParams;
        }

        @Deprecated
        public void isCustomParams(boolean customParams) {
            isCustomParams = customParams;
        }

        @Deprecated
        public void isCustomParams(boolean customParams,String inPath,String outPath) {
            isCustomParams = customParams;
            inParamsFilePath = inPath;
            outParamsFilePath = outPath;
        }

        @Deprecated
        public String inParamsFilePath() {
            return inParamsFilePath;
        }

        @Deprecated
        public String outParamsFilePath() {
            return outParamsFilePath;
        }

        public Configuration end() {
            return Configuration.this;
        }

        @Override
        public String toString() {
            return "MappingConfig{" +
                    "mappingTypes=" + Arrays.toString(mappingTypes) +
                    ", isCustomParams=" + isCustomParams +
                    ", inParamsFilePath='" + inParamsFilePath + '\'' +
                    ", outParamsFilePath='" + outParamsFilePath + '\'' +
                    ", tableMapping=" + tableMapping +
                    '}';
        }
    }

    public class POIConfig {

        private ExcelType excelType = ExcelType.HSSF;

        private String outPath = "D:/out-excel";

        public ExcelType excelType() {
            return excelType;
        }

        public POIConfig excelType(ExcelType excelType) {
            this.excelType = excelType;
            return this;
        }

        public String outPath() {
            return outPath;
        }

        public POIConfig outPath(String outPath) {
            this.outPath = outPath;
            return this;
        }

        public String fileExtension() {
            return excelType.equals(ExcelType.XSSF) ? ".xlsx":".xls";
        }

        public Configuration end() {
            return Configuration.this;
        }

        @Override
        public String toString() {
            return "POIConfig{" +
                    "excelType=" + excelType +
                    ", outPath='" + outPath + '\'' +
                    '}';
        }
    }

    public class TableMapping {

        private Map<String,String> tables = new HashMap<>();

        private Map<String,MappingType[]> mappingTypes = new HashMap<>();

        public TableMapping oneTable(String tableName,MappingType... types) {
            String string = UUID.randomUUID().toString();
            tables.put(tableName,string);
            mappingTypes.put(string,types);
            return this;
        }

        public TableMapping anyTables(String[] tableNames,MappingType... types) {
            String string = UUID.randomUUID().toString();
            Arrays.stream(tableNames)
                    .forEach(table -> {
                        tables.put(table,string);
                    });
            mappingTypes.put(string,types);
            return this;
        }

        public MappingType[] getMappingTypeByTableName(String tableName) {
            return mappingTypes.get(tables.get(tableName));
        }

        public MappingConfig end() {
            return Configuration.this.mppingConfig;
        }

        @Override
        public String toString() {
            return "TableMapping{" +
                    "tables=" + tables +
                    ", mappingTypes=" + mappingTypes +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "Configuration{" +
                "dbConfig=" + dbConfig +
                ", mppingConfig=" + mppingConfig +
                ", poiConfig=" + poiConfig +
                '}';
    }
}
